﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NBModular.Lib.Utils.Core.Attributes;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NBModular.Lib.Utils.Core.Helpers;
using NBModular.Lib.WeChat.Core.Auth.Models;

namespace NBModular.Lib.WeChat.Core.Auth
{
    /// <summary>
    /// 微信授权认证帮助类
    /// </summary>
    [Singleton]
    public class WeChatAuthHelper
    {
        /// <summary>
        /// 获取全局AccessToken
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="secret"></param>
        /// <returns>{"access_token":"ACCESS_TOKEN","expires_in":7200}</returns>
        /// <returns>{"errcode":40013,"errmsg":"invalid appid"}</returns>
        public async Task<string> GetTokenAsync(string appid, string secret)
        {
            return await Task.Run(() =>
            {
                var param = new Dictionary<string, object>();
                param.Add("grant_type", "client_credential");
                param.Add("appid", appid);
                param.Add("secret", secret);

                return HttpHelper.GetData(WeChatConst.CGI_BIN_TOKEN_URL, param);
            });
        }

        /// <summary>
        /// 获取微信用户认证信息
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="secret"></param>
        /// <param name="code"></param>
        /// <returns>{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE" }</returns>
        /// <returns>{"errcode":40029,"errmsg":"invalid code"}</returns>
        public async Task<string> GetOauth2InfoAsync(string appid, string secret, string code)
        {
            return await Task.Run(() =>
            {
                var param = new Dictionary<string, object>();
                param.Add("appid", appid);
                param.Add("secret", secret);
                param.Add("code", code);
                param.Add("grant_type", "authorization_code");

                return HttpHelper.GetData(WeChatConst.OAUTH2_ACCESS_TOKEN_URL, param);
            });
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="openid"></param>
        /// <returns>
        /// {   
        ///   "openid": "OPENID",
        ///   "nickname": NICKNAME,
        ///   "sex": 1,
        ///   "province":"PROVINCE",
        ///   "city":"CITY",
        ///   "country":"COUNTRY",
        ///   "headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
        ///   "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
        ///   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
        /// }
        /// </returns>
        /// <returns>{"errcode":40003,"errmsg":" invalid openid "}</returns>
        public async Task<string> GetUserInfoAsync(string access_token, string openid)
        {
            return await Task.Run(() =>
            {
                var param = new Dictionary<string, object>();
                param.Add("access_token", access_token);
                param.Add("openid", openid);

                return HttpHelper.GetData(WeChatConst.SNS_USERINFO_URL, param);
            });
        }

        /// <summary>
        /// 获取JSAPI-Ticket
        /// </summary>
        /// <param name="access_token"></param>
        /// <returns></returns>
        public async Task<string> GetTicketAsync(string access_token)
        {
            return await Task.Run(() =>
            {
                var param = new Dictionary<string, object>();
                param.Add("access_token", access_token);
                param.Add("type", "jsapi");

                return HttpHelper.GetData(WeChatConst.TICKET_GETTICKET_URL, param);
            });
        }

        /// <summary>
        /// 获取微信JS-SKD配置
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="jsapi_ticket"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public async Task<WxConfigModel> GetWxConfigAsync(string appId, string jsapi_ticket, string url)
        {
            return await Task.Run(() =>
            {
                StringHelper stringHelper = new StringHelper();
                WxConfigModel wxJsConfig = new WxConfigModel
                {
                    AppId = appId,
                    NonceStr = stringHelper.GenerateRandom(16),
                    Timestamp = DateTime.Now.ToTimestamp()
                };
                wxJsConfig.Signature = SignatureHelper.BuildTicketSignature(jsapi_ticket, wxJsConfig.NonceStr, wxJsConfig.Timestamp, url);
                return wxJsConfig;
            });
        }
    }
}
